package com.caiheng.api.service.estate.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.caiheng.api.constant.ResponseCode;
import com.caiheng.api.dao.estate.EstateMapper;
import com.caiheng.api.dao.estate.RepairRecordImgMapper;
import com.caiheng.api.dao.estate.RepairRecordInfoMapper;
import com.caiheng.api.dao.estate.RepairRecordMapper;
import com.caiheng.api.dao.sys.SysUserMapper;
import com.caiheng.api.entity.dto.RepairStepDto;
import com.caiheng.api.entity.estate.*;
import com.caiheng.api.entity.sys.SysUser;
import com.caiheng.api.entity.wxuser.User;
import com.caiheng.api.exception.TransactionalException;
import com.caiheng.api.rabbitmq.RabbitConfig;
import com.caiheng.api.rabbitmq.RabbitMqSender;
import com.caiheng.api.service.estate.EstateUserService;
import com.caiheng.api.service.estate.RepairRecordService;
import com.caiheng.api.service.platfom.WxTemplateService;
import com.caiheng.api.service.base.impl.BaseServiceImpl;
import com.caiheng.api.util.DateUtil;
import com.caiheng.api.util.GsonResultBean;
import com.caiheng.api.util.OrderUtil;
import com.caiheng.api.util.Tools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 报修记录Service业务层处理
 *
 * @author ruoyi
 * @date 2021-08-21
 */
@Service
public class RepairRecordServiceImpl extends BaseServiceImpl<RepairRecordMapper, RepairRecord> implements RepairRecordService {

    @Resource
    private RepairRecordMapper repairRecordMapper;
    @Resource
    private RepairRecordImgMapper repairRecordImgMapper;
    @Resource
    private RepairRecordInfoMapper repairRecordInfoMapper;
    @Resource
    private EstateUserService estateUserService;
    @Resource
    private WxTemplateService wxTemplateService;
    @Resource
    private SysUserMapper sysUserMapper;

    @Value("${web.imgPrefix}")
    private String imgPrefix;//微信支付的回调地址

    @Autowired
    private RabbitConfig rabbitConfig;
    private RabbitMqSender rabbitMqSender;

    @Autowired
    ThreadPoolTaskExecutor customAsyncThreadPool;

    @Override
    @Transactional
    public int addRecord(User user, RepairRecord repairRecord) {
        int ret = 0;
        try {
            String recordNo = OrderUtil.getRecordNo();
            repairRecord.setRecordNo(recordNo);
            EstateUser estateUser = estateUserService.getEstateManagerByUser(repairRecord.getEstateId(),1);
            if(estateUser!=null){
                repairRecord.setEsManagerWxUserId(estateUser.getUserId());
            }

            ret = repairRecordMapper.insert(repairRecord);
            if(ret > 0){
//                String param = "{\"type\" : \"repairRecord\"}";
//                RabbitTemplate rabbitTemplate = rabbitConfig.rabbitTemplate();
//                rabbitMqSender = new RabbitMqSender(rabbitTemplate);
//                rabbitMqSender.sendRabbitmqDirect("que_order_key",param);

                //客服人员  物业经理  维修人员 发送推送消息
                // 创建一个线程安全的队列
                Queue<RepairRecord> queue = new LinkedList<>();
                //指令
                queue.add(repairRecord);
                customAsyncThreadPool.submit(()->{
                    synchronized (queue){
                        while (!queue.isEmpty()){
                            RepairRecord repairRecord1 = queue.poll();
                            System.out.println("推送消息发送...");
                            wxTemplateService.sendWxMsgRepair(repairRecord1,0);
                        }
                    }
                });
            }
            ret = repairRecord.getId();
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("addRecord insert error");
        }
        return ret;
    }

    @Override
    @Transactional
    public int setWorker(User user, RepairRecord repairRecord) {
        int ret = 0;
        try{
            repairRecord.setState(1);
            repairRecord.setOpState(1);
            repairRecord.setEsHandleTime(new Date());
            EstateUser worker = estateUserService.findById(repairRecord.getOpWorkerId());
            if(worker != null){
                repairRecord.setOpWorkerId(worker.getId());
                repairRecord.setOpWxUserId(worker.getUserId());
                repairRecord.setOpWxNickName(worker.getNickName());
                if(worker.getSysUserId() != null){
                    SysUser sysUser = sysUserMapper.selectById(worker.getSysUserId());
                    if(sysUser != null){
                        repairRecord.setOpWorkerPhone(sysUser.getPhoneNum());
                        repairRecord.setOpUserName(sysUser.getNickName());
                    }
                }
            }

            ret = repairRecordMapper.updateById(repairRecord);
            if(ret > 0){
                wxTemplateService.sendWxMsgRepairToWorker(repairRecord,worker,0);
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("setWorker insert error");
        }
        return ret;
    }

    @Override
    @Transactional
    public int pickOp(User user,SysUser sysUser, EstateUser estateUser, RepairRecord repairRecord) {
        int ret = 0;
        try{
            //状态 0 - 待处理  1 - 已抢单 -  2 - 进行中  3 - 结束完成
            repairRecord.setState(1);

            repairRecord.setOpWorkerId(estateUser.getId());
            repairRecord.setOpWxUserId(estateUser.getUserId());
            repairRecord.setOpWxNickName(estateUser.getNickName());
            repairRecord.setOpWorkerPhone(sysUser.getPhoneNum());
            repairRecord.setOpUserName(sysUser.getNickName());

            ret = repairRecordMapper.updateById(repairRecord);
            if(ret <= 0){
                throw new TransactionalException("repairRecordMapper updateById error");
            }

            RepairRecordInfo recordInfo = new RepairRecordInfo();
            recordInfo.setWxUserId(user.getId());
            recordInfo.setRecordId(repairRecord.getId());
            //处理类型 0 - 指派  1 - 抢单 2 -   处理
            recordInfo.setHandleType(1);
            recordInfo.setSysUserId(sysUser.getUserId());
            recordInfo.setSysNickName(sysUser.getNickName());
            recordInfo.setPhoneNum(sysUser.getPhoneNum());
            recordInfo.setHandleTime(new Date());
            recordInfo.setCreateTime(new Date());
            recordInfo.setEstateUserId(estateUser.getId());
            recordInfo.setOpResult("抢单成功");
            recordInfo.setWxNickName(user.getNickName());
            ret = repairRecordInfoMapper.insert(recordInfo);
            if(ret <= 0){
                throw new TransactionalException("repairRecordInfoMapper insert error");
            }

        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("repairRecordInfoMapper insert error");
        }
        return ret;
    }

    @Override
    @Transactional
    public int handleRecord(User user, SysUser sysUser, EstateUser estateUser,String content, RepairRecord repairRecord) {
        int ret = 0;
        try {
            //状态 0 - 待处理  1 - 已抢单 -  2 - 进行中  3 - 结束完成
            if(repairRecord.getPickType() == 0){
                repairRecord.setOpResult(content);
                repairRecord.setState(2);
                repairRecord.setOpState(2);
            }else{
                repairRecord.setOpResult(content);
                repairRecord.setState(2);
                repairRecord.setOpState(2);
            }
            repairRecord.setOpTime(new Date());
            ret = repairRecordMapper.updateById(repairRecord);
            if(ret <= 0){
                throw new TransactionalException("repairRecordMapper updateById error");
            }


            RepairRecordInfo recordInfo = new RepairRecordInfo();
            recordInfo.setWxUserId(user.getId());
            recordInfo.setRecordId(repairRecord.getId());
            //处理类型 0 - 指派  1 - 抢单 2 - 处理  3 - 评价结束
            recordInfo.setHandleType(2);
            recordInfo.setSysUserId(sysUser.getUserId());
            recordInfo.setPhoneNum(sysUser.getPhoneNum());
            recordInfo.setSysNickName(sysUser.getNickName());
            recordInfo.setHandleTime(new Date());
            recordInfo.setCreateTime(new Date());
            recordInfo.setEstateUserId(estateUser.getId());
            recordInfo.setOpResult(content);
            recordInfo.setWxNickName(user.getNickName());
            ret = repairRecordInfoMapper.insert(recordInfo);
            if(ret <= 0){
                throw new TransactionalException("repairRecordInfoMapper insert error");
            }


//                String param = "{\"type\" : \"repairRecord\"}";
//                RabbitTemplate rabbitTemplate = rabbitConfig.rabbitTemplate();
//                rabbitMqSender = new RabbitMqSender(rabbitTemplate);
//                rabbitMqSender.sendRabbitmqDirect("que_order_key",param);

            //客服人员  物业经理  维修人员 发送推送消息
//                wxTemplateService.sendWxMsgRepair(repairRecord,1);

            ret = recordInfo.getId();
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("handleRecord insert error");
        }
        return ret;
    }

    @Override
    @Transactional
    public int appraiseOp(User user, String content, RepairRecord repairRecord) {
        int ret = 0;
        try{
            repairRecord.setState(3);
            ret = repairRecordMapper.updateById(repairRecord);
            if(ret <= 0){
                throw new TransactionalException("repairRecordMapper updateById error");
            }

            RepairRecordInfo recordInfo = new RepairRecordInfo();
            recordInfo.setWxUserId(user.getId());
            recordInfo.setRecordId(repairRecord.getId());
            //处理类型 0 - 指派  1 - 抢单 2 - 处理  3 - 评价结束
            recordInfo.setHandleType(3);
            recordInfo.setPhoneNum(user.getPhoneNum());
            recordInfo.setHandleTime(new Date());
            recordInfo.setCreateTime(new Date());
            recordInfo.setOpResult(content);
            recordInfo.setWxNickName(user.getNickName());
            ret = repairRecordInfoMapper.insert(recordInfo);
            if(ret <= 0){
                throw new TransactionalException("repairRecordInfoMapper insert error");
            }

        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("appraiseOp insert error");
        }
        return ret;
    }

    @Override
    public RepairRecord getRepairById(int record_id) {
        return getRepairRecord(repairRecordMapper.selectById(record_id));
    }

    @Override
    public List<RepairRecord> selectByUserId(Integer user_id, EstateUser estateUser, Integer state, Integer pageIndex, Integer pageSize) {
        QueryWrapper<RepairRecord> qw = new QueryWrapper<>();

        if(state > -1){
            qw.eq("state",state);
        }

        if(estateUser!= null){
            if(estateUser.getIsManager() == 0){
                qw.eq("user_id",user_id);
            }else{
                qw.eq("estate_id",estateUser.getEstateId());
            }
        }else{
            qw.eq("user_id",user_id);
        }

        qw.eq("is_del",0);
        qw.orderByDesc("create_time");
        List<RepairRecord> list = repairRecordMapper.getPageEntityList(qw,pageIndex,pageSize);
        list.forEach(repairRecord -> {
            repairRecord = getRepairRecord(repairRecord);
        });
        return list;
    }

    @Override
    public List<RepairRecord> selectEstateByUserId(Integer user_id, SysUser sysUser, EstateUser estateUser, Integer state, Integer pageIndex, Integer pageSize) {
        QueryWrapper<RepairRecord> qw = new QueryWrapper<>();
//        qw.eq("op_state",1);
        if(state > -1){
            qw.eq("state",state);
        }

        //工作人员 需要指派才能看到   经理可以看所有
        if(estateUser.getIsManager() == 0){
            //全部
            if(state == -1 || state == 2){//全部和 已结束的 物业经理 和 维修工都可以看
                qw.and(wrapper->{
                    wrapper.eq("op_wx_user_id",user_id).or().eq("es_manager_wx_user_id",user_id);
                });
            } else if(state == 0){//待处理 - 物业经理可以指派维修工
                qw.eq("es_manager_wx_user_id",user_id);
            } else if(state == 1){//维修工 可进行处理
                qw.eq("op_wx_user_id",user_id);
            }
        }else{
            qw.eq("estate_id",estateUser.getEstateId());
        }

        qw.eq("is_del",0);
        qw.orderByDesc("create_time");

        List<RepairRecord> list = repairRecordMapper.getPageEntityList(qw,pageIndex,pageSize);
        list.forEach(repairRecord -> {
//            repairRecord = getRepairRecord(repairRecord);
        });
        return list;
    }

    @Override
    public List<RepairRecord> selectMyPickList(Integer user_id, SysUser sysUser, EstateUser estateUser, Integer state, Integer pageIndex, Integer pageSize) {
        QueryWrapper<RepairRecord> qw = new QueryWrapper<>();
        if(state > -1){
            qw.eq("state",state);
        }else{
            //全部 只查询 我
            Integer[] states = { 1,2,3 };
            qw.in("state", states);
        }

        qw.eq("op_wx_user_id",user_id);

        qw.eq("is_del",0);
        qw.orderByDesc("create_time");

        List<RepairRecord> list = repairRecordMapper.getPageEntityList(qw,pageIndex,pageSize);
        list.forEach(repairRecord -> {
//            repairRecord = getRepairRecord(repairRecord);
        });
        return list;
    }

    @Override
    public List<RepairRecord> selectByEstateId(Integer estateId, Integer state, Integer pageIndex, Integer pageSize) {
        QueryWrapper<RepairRecord> qw = new QueryWrapper<>();
        qw.eq("state", state);
        qw.eq("estate_id", estateId);
        qw.eq("is_del",0);
        qw.orderByDesc("create_time");

        List<RepairRecord> list = repairRecordMapper.getPageEntityList(qw,pageIndex,pageSize);
        list.forEach(repairRecord -> {
//            repairRecord = getRepairRecord(repairRecord);
        });
        return list;
    }

    private RepairRecord getRepairRecord(RepairRecord repairRecord){
        List<String> imgUrls = new ArrayList<>();
        QueryWrapper<RepairRecordImg> qwRecordImg = new QueryWrapper<>();
        qwRecordImg.eq("record_id",repairRecord.getId());
        qwRecordImg.eq("img_type", 0);
        List<RepairRecordImg> recordImgs = repairRecordImgMapper.selectList(qwRecordImg);
        if(CollUtil.isNotEmpty(recordImgs)){
            for (RepairRecordImg recordImg : recordImgs){
                imgUrls.add(imgPrefix + recordImg.getImgUrl());
            }
            repairRecord.setImgUrlList(imgUrls);
        }


        List<RepairStepDto> stepInfos = new ArrayList<>();

        RepairStepDto stepFirst = new RepairStepDto();
        stepFirst.setStateTip("发起");
        stepFirst.setTitle("发起人：" + repairRecord.getNickName() + "(" + repairRecord.getPhoneNum() +")");
//        stepFirst.setContent("发起时间：" +  DateUtil.getTime(repairRecord.getCreateTime()));
        stepFirst.setTime("发起时间：" +  DateUtil.getTime(repairRecord.getCreateTime()));
        stepFirst.setState(1);
        stepInfos.add(stepFirst);


        QueryWrapper<RepairRecordInfo> qwInfo = new QueryWrapper<>();
        qwInfo.eq("record_id",repairRecord.getId());
        List<RepairRecordInfo> infos = repairRecordInfoMapper.selectList(qwInfo);
        if(CollUtil.isNotEmpty(infos)){
            for (RepairRecordInfo info : infos){
                RepairStepDto step = new RepairStepDto();
                // 处理类型 0 - 指派  1 - 抢单 2 - 处理  3 - 评价结束
                if(info.getHandleType() == 0){
                    step.setStateTip("指派");
                    step.setTitle("处理人：" + info.getSysNickName() + "(" + info.getPhoneNum() + ")");
                    step.setTime("处理时间：" + DateUtil.getTime(info.getHandleTime()));
                    step.setContent("处理结果：" + info.getOpResult());
                }else if(info.getHandleType() == 1){
                    step.setStateTip("抢单");
                    step.setTitle("处理人：" + info.getSysNickName() + "(" + info.getPhoneNum() + ")");
                    step.setTime("处理时间：" + DateUtil.getTime(info.getHandleTime()));
                    step.setContent("处理结果：" + info.getOpResult());
                }else if(info.getHandleType() == 2){
                    step.setStateTip("处理");
                    step.setTitle("处理人：" + info.getSysNickName() + "(" + info.getPhoneNum() + ")");
                    step.setTime("处理时间：" + DateUtil.getTime(info.getHandleTime()));
                    step.setContent("处理结果：" + info.getOpResult());
                }else if(info.getHandleType() == 3){
                    step.setStateTip("业主评价");
                    step.setTitle("评价人：" + info.getWxNickName() + "(" + info.getPhoneNum() + ")");
                    step.setTime("评价时间：" + DateUtil.getTime(info.getHandleTime()));
                    step.setContent("业主评价：" + info.getOpResult());
                    step.setRateStar(repairRecord.getRateStar());
                }
                step.setState(1);

                List<String> imgInfoUrls = new ArrayList<>();
                QueryWrapper<RepairRecordImg> qwRecordInfoImg = new QueryWrapper<>();
                qwRecordInfoImg.eq("info_id",info.getId());
                List<RepairRecordImg> recordInfoImgs = repairRecordImgMapper.selectList(qwRecordInfoImg);
                if(CollUtil.isNotEmpty(recordInfoImgs)){
                    for (RepairRecordImg recordImg : recordInfoImgs){
                        imgInfoUrls.add(imgPrefix + recordImg.getImgUrl());
                    }
                    step.setImgs(imgInfoUrls);
                }
                info.setImgs(imgInfoUrls);

                stepInfos.add(step);
            }
            repairRecord.setStepInfos(stepInfos);
            repairRecord.setInfos(infos);
        }


        List<String> opImgUrls = new ArrayList<>();
        QueryWrapper<RepairRecordImg> qwRecordOpImg = new QueryWrapper<>();
        qwRecordOpImg.eq("record_id",repairRecord.getId());
        qwRecordOpImg.eq("img_type", 1);
        List<RepairRecordImg> recordOpImgs = repairRecordImgMapper.selectList(qwRecordOpImg);
        if(CollUtil.isNotEmpty(recordImgs)){
            for (RepairRecordImg recordImg : recordOpImgs){
                opImgUrls.add(imgPrefix + recordImg.getImgUrl());
            }
            repairRecord.setOpImgUrlList(opImgUrls);
        }

        //维修工人
        List<String> workNames = new ArrayList<>();
        if(repairRecord.getPickType() == 0){
            QueryWrapper<EstateUser> qwEstateUser = new QueryWrapper<>();
            qwEstateUser.eq("estate_id",repairRecord.getEstateId());
            qwEstateUser.eq("state",1);
            qwEstateUser.eq("is_manager",0);
            List<EstateUser> estateUsers = estateUserService.list(qwEstateUser);
            if(CollUtil.isNotEmpty(estateUsers)){
                for (EstateUser worker : estateUsers){
                    workNames.add(worker.getNickName());
                }
            }
            repairRecord.setWorkers(estateUsers);
            repairRecord.setWorkerNames(workNames);
        }

        return repairRecord;
    }

}
